package com.impress;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;


import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Matrix.ScaleToFit;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.Log;


//import android.content.Context;
//import android.net.ConnectivityManager;
//import android.net.NetworkInfo;

//import android.util.Log;

public class Utility {

	private static final String TAG = "Utility";
	
	public static final String VIEW_STATE_FEED = "VIEW_STATE_FEED";
	public static final String VIEW_STATE_ITEM = "VIEW_STATE_ITEM";
	
	/*
	 * responses to a login request:
	 * success (HTTP 200)
	 * failure (HTTP 403) with an error code
	 * out of time (HTTP 401)--update for a new auth token.
	 * in the case of a bad/expired T token (used with GRAPI calls), 
	 * the request will return HTTP 400, and the HTTP headers will include "X-Reader-Google-Bad-Token: true."  
	 * Is there anything similar for a bad/expired auth token? 
	 * request for info needed login with auth="" responses "HTTP 400 Bad Request"
	 * */

	public static final String GOOGLE_LOGIN_URL = "https://www.google.com/accounts/ClientLogin";
	public static final String READER_URL = "http://www.google.com/reader/";
	
	public static final String GFWED_URL = "feeds.feedburner.com";
	/**
	 * 表示当前用户
	 */
	public static final String CURRENT_USER = "user/-/";
	
	/**
	 * 访问API的URL基本部分
	 * google.com/reader/api/0/；
	 */
	public static final String API_URL = READER_URL+"api/0/";
	/**
	 * API URL中的访问各list和post请求的基本部分
	 * google.com/reader/api/0/token/
	 */
	public static final String TOKEN_URL = API_URL+"token";
	/**
	 * API URL中的访问stream的基本部分
	 * google.com/reader/api/0/stream/
	 */
	public static final String STREAM_URL = API_URL+"stream/";
	
	/**
	 * API URL for editing.
	 * google.com.reader/api/0/edit-tag
	 */
	public static final String EDIT_TAG_URL = API_URL + "edit-tag";
	
	/**
	 * API URL中的访问feed内容的基本URL
	 * stream/contents/
	 */
	public static final String CONTENT_URL = STREAM_URL+"contents/";
	/**
	 * 访问feed内容(可能的使用方法：通过post请求来访问具体feed内容，提供参数i=item-ids)
	 * stream/items/contents/
	 */
	public static final String CONTENT_ITEM_URL = STREAM_URL+"items/contents";
	
	/**
	 * 访问items的ids 列表
	 * api/0/stream/items/ids
	 */
	public static final String ITEM_IDS_URL = STREAM_URL + "items/ids";
	/**
	 * 通过atom方式访问feed内容的基本URL
	 * google.com/reader/atom/
	 */
	public static final String ATOM_URL = READER_URL+"atom/";
	
	/**
	 * URL中表示条目状态的前缀
	 * user/-/state/com.google/
	 */
	public static final String ITEM_STATE = CURRENT_USER + "state/com.google/";
	
	/**
	 * 表示一个已读状态的条目
	 */
	public static final String ITEM_READ_STATE = ITEM_STATE + "read";
	
	/**
	 * 所有的条目都是reading-list状态
	 * (All your items are in reading-list state.)
	 */
	public static final String ITEM_READINGLIST_STATE = ITEM_STATE + "reading-list";
	
	public static final String ITEM_STARED_STATE = ITEM_STATE +"starred";
	
	public static final String ITEM_LIKED_STATE = ITEM_STATE + "liked";
	
	public static final String ITEM_KEPTUNREAD_STATE = ITEM_STATE + "kept-unread";
	
	public static final String ITEM_BROADCAST_STATE = ITEM_STATE + "broadcast";
	
	/**
	 * 用于访问某个具体feed的前缀，后接feed url.
	 */
	public static final String FEED_PREFIX = "feed/";
	
	/**
	 * 用于访问标签的前缀,后接label name.
	 */
	public static final String LABEL_PREFIX = CURRENT_USER + "label/";

	
	/**
	 * 排除的条目状态<br>
	 *  http get请求参数：xt
	 */
	public static final String PARAMETER_XT = "xt";
	
	/**
	 * request state of item<br>
	 * http get parameter: s
	 */
	public static final String PARAMETER_S = "s";
	
	/**
	 * item id<br>
	 * http post parameter: i
	 */
	public static final String PARAMETER_I = "i";
	
	/**
	 * add an state.<br>
	 * http post parameter: a
	 */
	public static final String PARAMETER_A = "a";
	
	
	/**
	 * token for authorized post request.<br>
	 * http post parameter: T
	 */
	public static final String PARAMETER_T = "T";
	
	/**
	 * 数目<br>
	 * HTTP请求参数：n
	 */
	public static final String PARAMETER_N = "n";
	
	/**
	 * 时间截止点<br>
	 * Http请求参数: ot
	 */
	public static final String PARAMETER_OT = "ot";
	
	/**
	 * 时间戳，防缓存<br>
	 * Http请求参数: ck
	 */
	public static final String PARAMETER_CK = "ck";
	
	/**
	 * 顺序 [d/n/o] or remove a state<br>
	 * Http请求参数 or http post parameter：r
	 */
	public static final String PARAMETER_R = "r";
	
	/**
	 * output format[xml,json]
	 * http Get parameter: output
	 */
	public static final String PARAMETER_OUTPUT = "output";
	
	/**
	 * Http请求参数: client
	 */
	public static final String PARAMETER_CLIENT = "client";
	
	/**
	 * json字串中的items结点名称:items
	 */
	public static final String JSON_NODE_ITEMS = "items";
	
	/**
	 * json字串中的更新时间结点名称:updated
	 */
	public static final String JSON_NODE_UPDATED = "updated";
	
	/**
	 * json字串中的id结点名称：id
	 */
	public static final String JSON_NODE_ID = "id";
	
	/**
	 * json字串中的种类结点名称: categories
	 */
	public static final String JSON_NODE_CATEGORY = "categories";
	
	/**
	 * json字串中的标题结点名称：title
	 */
	public static final String JSON_NODE_TITLE = "title";
	
	/**
	 * json字串中的原网址结点名称：alternate
	 */
	public static final String JSON_NODE_ALTERNATE = "alternate";
	
	/**
	 * json字串中的网址地址结点名称：href
	 */
	public static final String JSON_NODE_HREF = "href";
	
	/**
	 * json字串中的内容结点名称：content
	 */
	public static final String JSON_NODE_CONTENT = "content";
	
	/**
	 * json字串中的内容结点名称：summary
	 */
	public static final String JSON_NODE_SUMMARY = "summary";
	
	/**
	 * json字串中的作者结点名称：author
	 */
	public static final String JSON_NODE_AUTHOR = "author";
	
	/**
	 * json字串中的feed结点名称:origin
	 */
	public static final String JSON_NODE_ORIGIN = "origin";
	
	/**
	 * json字串中的feed名称结点名称：streamId
	 */
	public static final String JSON_NODE_STREAMID = "streamId";
	
	/**
	 * json strings node name: itemRefs. contain in ids api.
	 */
	public static final String JSON_NODE_ITEMREFS = "itemRefs";
	
	/**
	 * json node: timestamUsec.
	 */
	public static final String JSON_NODE_TIMESTAMPUSEC = "timestampUsec";
	
	//private static HttpPost httpPost;
	//private static HttpGet httpGet;
	//private static HttpResponse response;
	
	public static final int NETWORKTYPE_WIFI = 1;
	public static final int NETWORKTYPE_ALL = NETWORKTYPE_WIFI + 1;
	
	
	/**
	 * 构造http url的参数串
	 * @param strings 参数对，前者为参数名，后者为参数值，可以接任意对字串
	 * 如："n","20","ot","120000102"
	 * @return 返回参数对的字符串
	 * 如："n=20&ot=1200000102"
	 */
	public static String makeupParameter(String...strings ){
		int count = strings.length;
		StringBuilder sBuilder = new StringBuilder();
		
		if(count < 2)   //如果参数个数小于2，即为0或1，则不构成参数对，返回空字串
			return "";
		for(int i = 0; i<count-1; i++)
		{
			sBuilder.append(strings[i]+"="+strings[++i]+"&");
		}
		return sBuilder.toString();
	}
	
	/**
	 * make up post params
	 * @param strings null string will be ignored.
	 * @return
	 */
	public static List<NameValuePair> makeupPostParameter(String...strings){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		int count = strings.length;
		if(count<2) //if params count less than 2, is 0 or 1, so can't make a params match
			return params;
		
		for(int i = 0; i<count-1;i++){
			if (strings[i] != null && strings[i+1] != null) {
				params.add(new BasicNameValuePair(strings[i], strings[++i]));
			}			
		}
		
		return params;
	}
	
	public static String parseItemId(String idString){
		int i = idString.lastIndexOf('/');
		idString = idString.substring(i+1, idString.length());
		return idString;
	}
	
	public static boolean isAds(String src){
		String[] adsBlock = {
			"http://feeds.feedburner.com/",
			"http://www1.feedsky.com",
			"http://feedads.g.doubleclick.net/",
			"http://res3.feedsportal.com",
			"http://da.feedsportal.com"
		};
		for (String string : adsBlock) {
			if(src.startsWith(string)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * convert the long value to an item id.
	 * @param id
	 * @return
	 */
	public static String convertLongToItemId(long id){
		String idString = "tag:google.com,2005:reader/item/" + convertLongToHex(id);
		return idString;
	}
	
	/**
	 * convert the item id to long value
	 * @param idString like: "tag:google.com,2005:reader/item/39712f2cb94dfaf4"
	 * @return
	 */
	public static long convertItemIdToLong(String idString){
		
		return convertHexToLong(parseItemId(idString));
	}
	
	/**
	 * convert a long value to a hex string
	 * @param longValue
	 * @return
	 */
	public static String convertLongToHex(long longValue){
		return Long.toHexString(longValue);
	}
	
	/**
	 * convert a hex string to a long value
	 * @param hexString
	 * @return a string of long value.
	 */
	public static long convertHexToLong(String hexString){
		return new BigInteger(hexString, 16).longValue();
	}
	
	
	public static String convertLongToDate(long longValue){
		return new Date(longValue).toLocaleString();
		
	}
	/**
	 * sub string if longer than length
	 * @param str
	 * @param length
	 * @return
	 */
	public static String trimString(String str, int length){
		if (str.length() > length) {
			return str.substring(0, length-1) + "...";
		}else {
			return str;
		}
	}
	/**
	 * convert the stream to bytes.
	 * @param is
	 * @return
	 */
	public static byte[] convertStreamToBytes(InputStream is){
		byte[] bResult = null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			byte[] buf = new byte[1024];
			int num = -1;
			while ((num = is.read(buf))!= -1) {
				baos.write(buf, 0, num);
			}
			bResult = baos.toByteArray();
			baos.flush();
			baos.close();
		} catch (Exception e) {
			// TODO: handle exception
		}finally{
			try {
				baos.close();
				is.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
		return bResult;
	}
	
	/**
	 * 将返回的流转换为字符串
	 * @param is
	 * @return
	 */
	public static String convertStreamToString(InputStream is){
		BufferedReader reader =
			new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();
		String line = null;
		try{
			while((line = reader.readLine())!=null){
				sb.append(line);
			}
		}
		catch(IOException e){
			//Log.e(TAG, e.getMessage());
			e.printStackTrace();
		}
		finally{
			try{
				is.close();
			}
			catch(IOException e){
				//Log.e(TAG, e.getMessage());
			}
		}
		return sb.toString();
	}
	
	/**
	 * delete file(may be directory)
	 * @param file
	 */
	public static void deleteFile(File file){
		if (!file.exists()) {
			return ;
		}
		if (file.isDirectory()) {
			if (file.listFiles().length == 0) {
				file.delete();
			}else {
				File[] files = file.listFiles();
				int length = files.length;
				for (int index = 0; index < length; index++) {
					deleteFile(files[index]);
				}
				file.delete();
			}
		}else {
			file.delete();
		}
	}

	public static boolean EmptyString(String str){
		return (TextUtils.isEmpty(str) || TextUtils.isEmpty(str.trim()));
	}
	
	public static Bitmap resizeImage(Bitmap image, int width, int height){
	    if(image.getWidth()<width &&
	        image.getHeight()<height){
	      return image;
	    }
	    
	    Matrix matrix = new Matrix(); 
	    int imgWidth = image.getWidth();
	    int imgHeight = image.getHeight();
	    
	    if(imgWidth<imgHeight){
	    	imgHeight = imgWidth;
	    }else{
	    	imgWidth = imgHeight;
	    }
	    RectF src = new RectF(0, 0, 
	        imgWidth, imgHeight);
	    RectF dist = new RectF(0, 0, width, height);

	    matrix.setRectToRect(src, dist, ScaleToFit.CENTER); 
	    Bitmap bitmap =Bitmap.createBitmap(
		        image, 
		        0, 0, 
		        imgWidth, 
		        imgHeight, 
		        matrix, true); 
	    image.recycle();
	    return bitmap; 
	  }
//	private Context mContext;
//	
//	public Utility(){
//		super();
//		mContext = null;
//	}
//	
//	public Utility(Context context){
//		super();
//		mContext = context;
//	}


	
	/**
	 * exception for http 403 status
	 */
	public static class HttpForbiddenException extends Exception{

	/**
	 * 
	 */
		private static final long serialVersionUID = 1L;
	
		public HttpForbiddenException() {
			super();
		}
		
		public HttpForbiddenException(String message){
			super(message);
		}
		
		public HttpForbiddenException(String message, Throwable e){
			super(message, e);
		}
	}

	
	/**
	 * exception for http 401 status: expired auth.
	 * @author pluto
	 *
	 */
	public static class HttpUnauthorizedException extends Exception{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public HttpUnauthorizedException() {
			super();
		}

		public HttpUnauthorizedException(String detailMessage,
				Throwable throwable) {
			super(detailMessage, throwable);
		}

		public HttpUnauthorizedException(String detailMessage) {
			super(detailMessage);
		}		
	}
	
	
	/**
	 * Exception for HTTP 400: bad/expired token.
	 * @author pluto
	 *
	 */
	public static class InvalidTokenException extends Exception{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		
		public InvalidTokenException(){
			super();
		}
		
		public InvalidTokenException(String detailMessage,
				Throwable throwable){
			super(detailMessage, throwable);
		}
		
		public InvalidTokenException(String detailMessage){
			super(detailMessage);
		}
		
	}
	
	
	/**
	 * exception for bad account info.
	 * This exception to get user to type their account info again.
	 * @author pluto
	 *
	 */
	public static class BadAccountException extends Exception{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
	

		public BadAccountException(){
			super();
		}
		
		public BadAccountException(String detailMessage){
			super(detailMessage);
		}
		
		public BadAccountException(String detailMessage,
				Throwable throwable){
			super(detailMessage, throwable);
		}
	}
	
	public static class SDCardException extends Exception{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public SDCardException() {
			super();
			// TODO Auto-generated constructor stub
		}

		public SDCardException(String detailMessage, Throwable throwable) {
			super(detailMessage, throwable);
			// TODO Auto-generated constructor stub
		}

		public SDCardException(String detailMessage) {
			super(detailMessage);
			// TODO Auto-generated constructor stub
		}

		public SDCardException(Throwable throwable) {
			super(throwable);
			// TODO Auto-generated constructor stub
		}
		
	}



	
}
